/**
 * @file        gtd.hpp
 * @brief       Defines specific methods related with todo items.
 *
 * @author      Emre Turkay <emreturkay at gmail>
 * @date        May.31.2008
 */

#ifndef _GTD_HPP_
#define _GTD_HPP_

#include <stdexcept>
#include <string>
#include <list>
#include <iterator>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <vector>

#include <boost/optional.hpp>
#include <boost/none.hpp>

#include "projects.hpp"

namespace gtd
{

    /*
     * Exceptions.
     */

    struct no_item: std::runtime_error
    {
        no_item(): std::runtime_error("No more items") { }
    };

    struct unknown_project: std::runtime_error
    {
        unknown_project(const std::string& name)
            : std::runtime_error(std::string("Unknown project: ") + name)
        {
        }
    };

    struct gtd
    {
        typedef size_t project_id;
        typedef std::map<project_id, project> projects;

        gtd();

        void save_done(std::ostream& os);

        project_id top_project() const;

        project& get_project(project_id index);

        const project& get_project(project_id index) const;

        void done();

        void cancel();

        void defer();

        void append(const std::string& value);

        void prepend(const std::string& value);

        void move_back();

        bool empty() const;

        std::vector<std::string> project_names() const;

        std::list<project_id> project_ids() const;

        std::list<project::action_id> items(project_id id) const;

        const action& item(project_id id, project::action_id index) const;

        size_t item_count(project_id id) const;

        boost::optional<project_id> find_project(const std::string& name) const;

    private:
        boost::optional<std::string>
        project_name(const std::string& line) const;

        project_id create_project(boost::optional<std::string> name);

    private:
        projects projects_;
        std::list<project_id> list_;
        std::list<std::string> done_items_;
    };

} // namespace gtd

#endif // _GTD_HPP_
